﻿using Coldairarrow.Entity;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.Entity.Goods;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using Coldairarrow.Util.DbHelpers;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Coldairarrow.Business
{
    public class Outbound_DetailsBusiness : BaseBusiness<Outbound_Details>, IOutbound_DetailsBusiness, ITransientDependency
    {
        readonly IOperator _Operator;
        public Outbound_DetailsBusiness(IDbAccessor db, IOperator Operatosr)
            : base(db)
        {
            _Operator = Operatosr;
        }

        #region 外部接口

        public async Task<PageResult<Outbound_Details>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<Outbound_Details>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<Outbound_Details, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<Outbound_Details> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(Outbound_Details data)
        {
            await InsertAsync(data);
        }

        public async Task UpdateDataAsync(Outbound_Details data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        /// <summary>
        /// 反向出库
        /// </summary>
        /// <returns></returns>
        public async Task outBound(Outbound_Details _Details)
        {

            var price = await Db.GetIQueryable<BTB_GoodsSpecificationsItem>().SingleOrDefaultAsync(s => s.GoodsSpecificationsItemID.Equals(_Details.Products_Id));
            if (price != null)
            {
                var dbawait = await Db.RunTransactionAsync(async () =>
                {
                    Outbound_Details _Detailsd = new Outbound_Details
                    {
                        Id = IdHelper.GetId(),
                        Deleted = false,
                        CreateTime = DateTime.Now,
                        CreatorId = _Operator.UserId,
                        Product_Id = _Details.Product_Id,
                        Products_Id = _Details.Products_Id,
                        productName = _Details.productName,
                        productsName = _Details.productsName,
                        Outbound_Num = _Details.Outbound_Num,//出入库数量
                        OrderMater_Id = "0",
                        OrderCode = "0",
                        Price = price.Price,
                        oldBalance = price.Inventory,
                        newBalance = (price.Inventory - (int)_Details.Outbound_Num),
                        Bound_Flag = 1,
                        DATA0 = "0",
                        TotalPrice = (decimal)(_Details.Outbound_Num * price.Price)
                    };
                    await InsertAsync(_Detailsd);
                    price.Inventory = price.Inventory - (int)_Details.Outbound_Num;
                    await Db.UpdateAsync<BTB_GoodsSpecificationsItem>(price);

                });
                if (dbawait.Success == false)
                {
                    throw dbawait.ex;
                }

            }


        }

        /// <summary>
        /// 获取出库明细
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<OutDetailDTO>> GetDataTwo(PageInput<Outbound_DetailsDto> input)
        {
            Expression<Func<Outbound_Details, Order_Master, BTB_StaffUser, OutDetailDTO>> select = (a, b, c) => new OutDetailDTO
            {
                OrderUserId = c.id,
                OrderUserNickName = c.NickName,
                OrderUserRealName = c.RealName,
                OrderUserPhone = c.phone
                
            };

            var t = input.Search;
            select = select.BuildExtendSelectExpre();

            var res = from a in Db.GetIQueryable<Outbound_Details>().AsExpandable()
                      join b in Db.GetIQueryable<Order_Master>() on a.OrderMater_Id equals b.Id into ab
                      from b in ab.DefaultIfEmpty()
                      join c in Db.GetIQueryable<BTB_StaffUser>() on b.CreatorId equals c.id into ac
                      from c in ac.DefaultIfEmpty()
                      join d in Db.GetIQueryable<BTB_Goods>() on a.Product_Id equals d.ID
                      join e in Db.GetIQueryable<BTB_GoodsSpecificationsItem>() on a.Products_Id equals e.GoodsSpecificationsItemID
                      select @select.Invoke(a, b, c);

            if (!t.productName.IsNullOrEmpty())
            {
                res = res.Where(p => p.productsName.Contains(t.productName));
            }
            if (t.startTime!=null)
            {
                res = res.Where(p => p.CreateTime>= t.startTime&&p.CreateTime<=t.endTime);
            }

            int count = res.ToList().Count;
            var data=await res.OrderByDescending(p=>p.CreateTime)
                .Skip((input.PageIndex - 1) * input.PageRows)
                .Take(input.PageRows)
                .ToListAsync();
            return new PageResult<OutDetailDTO>() { Data = data, Total = count };
          
        }
        /// <summary>
        /// 获取出库统计
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<Outbound_Infor>> GetDatastationTwo(PageInput<Outbound_DetailsDto> input)
        {

            
            var t = input.Search;
            StringBuilder builder1 = new StringBuilder();
            //builder1.Append(" select COUNT(Id) Num from Outbound_Details ");
            //// builder1.Append("  t inner join  ");
            //// builder1.Append("(select f.Products_Id, COUNT(f.Id) counts, SUM(f.Outbound_Num) num from Outbound_Details f Group by f.Products_Id) k on  t.Products_Id = k.Products_Id ");
            //if (!t.productName.IsNullOrEmpty())
            //{
            //    builder1.Append($" where productName= '{t.productName}' ");
            //}
           
            StringBuilder builder = new StringBuilder();
            builder.Append(" select a.GoodsName productName,b.GoodsSpecifications productsName,K.counts PutCount,K.num PutNum, t.Product_Id,t.Products_Id from Outbound_Details t  ");
            builder.Append(" inner join BTB_Goods a on a.Id = t.Product_Id ");
            builder.Append(" inner join BTB_GoodsSpecificationsItem b on b.GoodsSpecificationsItemID = t.Products_Id ");
            builder.Append(" inner join (select f.Products_Id, COUNT(f.Id) counts, SUM(f.Outbound_Num) num from Outbound_Details f Group by f.Products_Id) k on  t.Products_Id = k.Products_Id ");
            if (!t.productName.IsNullOrEmpty())
            {
                builder.Append($" where a.productName like '%{t.productName}%' ");
            }
            builder.Append($" order by t.Product_Id  ");
            //builder.Append($" OFFSET({input.PageRows} * ({input.PageIndex} - 1)) ROWS FETCH NEXT {input.PageRows} ROWS ONLY ");
            var count = 0;
            try
            {
                var dList = DbHelperSQL.QueryForList<Outbound_Infor>(builder.ToString());
                count = dList.Count;
                var data = dList.Skip(input.PageRows * (input.PageIndex - 1)).Take(input.PageRows).ToList();
                return new PageResult<Outbound_Infor>() { Data = data, Total = count };
            }
            catch (Exception e)
            {

                throw;
            }
            
          //  string str = "  select * from Outbound_Details t inner join " +
          //" (select f.Products_Id, COUNT(f.Id) counts, SUM(f.Outbound_Num) num from Outbound_Details f Group by f.Products_Id) k on  t.Products_Id = k.Products_Id " +

          //$"  order by t.CreateTime OFFSET({input.PageRows} * ({input.PageIndex} - 1)) " +
          //$"ROWS FETCH NEXT {input.PageRows} ROWS ONLY ";
            //var res = Db.GetIQueryable<Outbound_Details>();
            //var t = input.Search;
            //if (!t.productName.IsNullOrEmpty())
            //{
            //    res = res.Where(p => p.productsName.Contains(t.productName));
            //}
            //int count = res.ToList().Count;
            //var data = await res.OrderBy(p => p.CreateTime)
            //  .Skip((input.PageIndex - 1) * input.PageRows)
            //  .Take(input.PageRows)
            //  .ToListAsync();
            //Outbound_Infor _Infor = new Outbound_Infor
            //{

            //};
           
        }

        #endregion

        #region 私有成员
        private class data
        {
            public int Num { get; set; }
        }
   
        #endregion
    }
}